package gameengine.map;

import java.util.Observable;

import util.Logger;
import enumm.GROUND;
import gameengine.map.unit.Unit;

/**
 * The class Field represents a single square of the map. This means the Map is
 * made out of Fields. It can contain Units.
 */
public final class Field extends Observable implements Cloneable {

    private transient GROUND ground;

    private Unit unit;

    private transient int xCoordinate;
    private transient int yCoordinate;

    private int party;
    private transient int[] border;
    private transient boolean[] corner;

    public Field(final GROUND underground, final int buildingParty) {
        super();
        this.ground = underground;
        this.party = buildingParty;
    }

    public Field(final GROUND underGround) {
        super();
        this.ground = underGround;
        this.party = 0;
    }

    public Field(final int buildingParty) {
        super();
        this.ground = GROUND.BUILDING;
        this.party = buildingParty;
    }

    public void setUnit(final Unit unitOfField) {
        this.unit = unitOfField;
        setChanged();
        notifyObservers(new Point(this.xCoordinate, this.yCoordinate));
    }

    public void initWater(final int[] waterBorder, final boolean[] waterCorner) {
        this.border = waterBorder.clone();
        this.corner = waterCorner.clone();
        setChanged();
        notifyObservers(new Point(this.xCoordinate, this.yCoordinate));
    }

    public Unit getUnit() {
        return this.unit;
    }

    public GROUND getGround() {
        return this.ground;
    }

    @Override
    public Object clone() {
        Field field;
        try {
            field = (Field) super.clone();
            field.ground = this.ground;
            field.party = this.party;
            field.unit = this.unit;
            field.xCoordinate = this.xCoordinate;
            field.yCoordinate = this.yCoordinate;
        } catch (final CloneNotSupportedException e) {
            Logger.d("Field.clone()", e.getMessage());
            field = null;
        }

        return field;
    }

    @Override
    public String toString() {
        String string;
        if (this.unit == null) {
            switch (this.ground) {
            case WATER:
                string = "~";
                break;
            case GRASS:
                string = " ";
                break;
            case MOUNTAIN:
                string = "^";
                break;
            case FOREST:
                string = "T";
                break;
            default:
                Logger.d("Field.toString()", Logger.SWITCH_CASE_DEFAULT);
                string = "X";
            }
        } else {
            string = this.unit.toString();
        }
        return string;
    }

    public void setCoordinates(final int xCoord, final int yCoord) {
        this.xCoordinate = xCoord;
        this.yCoordinate = yCoord;
    }

    public int getParty() {
        return this.party;
    }

    public void setParty(final int newParty) {
        this.party = newParty;
    }

    public int[] getBorder() {
        return border;
    }

    public boolean[] getCorner() {
        return corner;
    }
}
